<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>鱼皮的编程宝典</title>
    <meta name="generator" content="VuePress 1.9.10">
    <link rel="icon" href="/favicon.ico">
    <script>
        var _hmt = _hmt || [];
        (function() {
          var hm = document.createElement("script");
          hm.src = "https://hm.baidu.com/hm.js?2675818a983a3131404cee835018f016";
          var s = document.getElementsByTagName("script")[0]; 
          s.parentNode.insertBefore(hm, s);
        })();
      </script>
    <meta name="description" content="贴心的编程学习路线，全面的编程知识百科">
    <meta property="article:modified_time" content="2023-11-11T12:17:47.000Z">
    <meta property="og:site_name" content="鱼皮的编程宝典">
    <meta property="og:type" content="article">
    <meta property="og:url" content="https://codefather.cn/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/">
    <meta name="twitter:url" content="https://codefather.cn/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/">
    <meta name="twitter:card" content="summary_large_image">
    <meta name="twitter:label1" content="Written by">
    <meta name="twitter:label2" content="Filed under">
    <meta name="twitter:data2" content="程序员, 编程, 计算机">
    <meta property="article:tag" content="程序员">
    <meta name="keywords" content="程序员鱼皮, 编程学习路线, 编程知识百科, Java, 编程导航, 前端, 开发, 编程分享, 项目, IT, 求职, 面经">
    
    <link rel="preload" href="/assets/css/0.styles.40c15e22.css" as="style"><link rel="preload" href="/assets/js/app.12ab4756.js" as="script"><link rel="preload" href="/assets/js/2.fd06b53e.js" as="script"><link rel="preload" href="/assets/js/203.3f50a6ed.js" as="script"><link rel="prefetch" href="/assets/js/1.17ea1209.js"><link rel="prefetch" href="/assets/js/10.d9532d8f.js"><link rel="prefetch" href="/assets/js/100.064ea126.js"><link rel="prefetch" href="/assets/js/101.d64c5b33.js"><link rel="prefetch" href="/assets/js/102.5e29a62c.js"><link rel="prefetch" href="/assets/js/103.59ad6cd7.js"><link rel="prefetch" href="/assets/js/104.ae4763e8.js"><link rel="prefetch" href="/assets/js/105.2a9124be.js"><link rel="prefetch" href="/assets/js/106.529bca07.js"><link rel="prefetch" href="/assets/js/107.c8671a0d.js"><link rel="prefetch" href="/assets/js/108.55c93c64.js"><link rel="prefetch" href="/assets/js/109.7d1efa54.js"><link rel="prefetch" href="/assets/js/11.2f89b5eb.js"><link rel="prefetch" href="/assets/js/110.0caecbf5.js"><link rel="prefetch" href="/assets/js/111.a2aeae49.js"><link rel="prefetch" href="/assets/js/112.eb7ceda5.js"><link rel="prefetch" href="/assets/js/113.f304408d.js"><link rel="prefetch" href="/assets/js/114.988c637f.js"><link rel="prefetch" href="/assets/js/115.bfdeed31.js"><link rel="prefetch" href="/assets/js/116.a47b8c53.js"><link rel="prefetch" href="/assets/js/117.2e1e8250.js"><link rel="prefetch" href="/assets/js/118.758ce408.js"><link rel="prefetch" href="/assets/js/119.73d9e688.js"><link rel="prefetch" href="/assets/js/12.53aaa509.js"><link rel="prefetch" href="/assets/js/120.202a8b2e.js"><link rel="prefetch" href="/assets/js/121.ca91d59a.js"><link rel="prefetch" href="/assets/js/122.8804c0dd.js"><link rel="prefetch" href="/assets/js/123.ceada225.js"><link rel="prefetch" href="/assets/js/124.4b2718b7.js"><link rel="prefetch" href="/assets/js/125.72134235.js"><link rel="prefetch" href="/assets/js/126.167b162c.js"><link rel="prefetch" href="/assets/js/127.f8139c17.js"><link rel="prefetch" href="/assets/js/128.da64a377.js"><link rel="prefetch" href="/assets/js/129.c07963b1.js"><link rel="prefetch" href="/assets/js/13.52940164.js"><link rel="prefetch" href="/assets/js/130.f66fc8bb.js"><link rel="prefetch" href="/assets/js/131.a913c7dd.js"><link rel="prefetch" href="/assets/js/132.ea648654.js"><link rel="prefetch" href="/assets/js/133.074ca70e.js"><link rel="prefetch" href="/assets/js/134.dc79ddd8.js"><link rel="prefetch" href="/assets/js/135.c4516208.js"><link rel="prefetch" href="/assets/js/136.2546baf7.js"><link rel="prefetch" href="/assets/js/137.56454fc6.js"><link rel="prefetch" href="/assets/js/138.bdb002bf.js"><link rel="prefetch" href="/assets/js/139.40a2f9b5.js"><link rel="prefetch" href="/assets/js/14.ade1e74d.js"><link rel="prefetch" href="/assets/js/140.06b20427.js"><link rel="prefetch" href="/assets/js/141.8dd992e3.js"><link rel="prefetch" href="/assets/js/142.d9305485.js"><link rel="prefetch" href="/assets/js/143.41bf907e.js"><link rel="prefetch" href="/assets/js/144.c138960c.js"><link rel="prefetch" href="/assets/js/145.fc5b38c8.js"><link rel="prefetch" href="/assets/js/146.c9166b70.js"><link rel="prefetch" href="/assets/js/147.c31d8a01.js"><link rel="prefetch" href="/assets/js/148.5c0534ca.js"><link rel="prefetch" href="/assets/js/149.d2355ea2.js"><link rel="prefetch" href="/assets/js/15.970a8ca5.js"><link rel="prefetch" href="/assets/js/150.c1644898.js"><link rel="prefetch" href="/assets/js/151.b6e4adf0.js"><link rel="prefetch" href="/assets/js/152.7a5071aa.js"><link rel="prefetch" href="/assets/js/153.31abbc68.js"><link rel="prefetch" href="/assets/js/154.9c6bb079.js"><link rel="prefetch" href="/assets/js/155.e5506a40.js"><link rel="prefetch" href="/assets/js/156.992dab50.js"><link rel="prefetch" href="/assets/js/157.12a6ee84.js"><link rel="prefetch" href="/assets/js/158.84dc1045.js"><link rel="prefetch" href="/assets/js/159.fd2022b1.js"><link rel="prefetch" href="/assets/js/16.ff971500.js"><link rel="prefetch" href="/assets/js/160.8d8889cd.js"><link rel="prefetch" href="/assets/js/161.31797def.js"><link rel="prefetch" href="/assets/js/162.bfae7a75.js"><link rel="prefetch" href="/assets/js/163.e5e8094d.js"><link rel="prefetch" href="/assets/js/164.870f212c.js"><link rel="prefetch" href="/assets/js/165.8da20a31.js"><link rel="prefetch" href="/assets/js/166.950a187d.js"><link rel="prefetch" href="/assets/js/167.fd042c52.js"><link rel="prefetch" href="/assets/js/168.7d9f058d.js"><link rel="prefetch" href="/assets/js/169.205df80e.js"><link rel="prefetch" href="/assets/js/17.4b045b26.js"><link rel="prefetch" href="/assets/js/170.270108a3.js"><link rel="prefetch" href="/assets/js/171.9f03d27d.js"><link rel="prefetch" href="/assets/js/172.1882bac7.js"><link rel="prefetch" href="/assets/js/173.fc1fe7d4.js"><link rel="prefetch" href="/assets/js/174.d77c927b.js"><link rel="prefetch" href="/assets/js/175.019b9e83.js"><link rel="prefetch" href="/assets/js/176.5ce31bd8.js"><link rel="prefetch" href="/assets/js/177.9a2006f2.js"><link rel="prefetch" href="/assets/js/178.88265ac1.js"><link rel="prefetch" href="/assets/js/179.3205ce07.js"><link rel="prefetch" href="/assets/js/18.1cdd0514.js"><link rel="prefetch" href="/assets/js/180.2ff51f44.js"><link rel="prefetch" href="/assets/js/181.f792ce97.js"><link rel="prefetch" href="/assets/js/182.103328e1.js"><link rel="prefetch" href="/assets/js/183.40fde303.js"><link rel="prefetch" href="/assets/js/184.1f36ac78.js"><link rel="prefetch" href="/assets/js/185.cf3b1c00.js"><link rel="prefetch" href="/assets/js/186.f7981399.js"><link rel="prefetch" href="/assets/js/187.20fe296d.js"><link rel="prefetch" href="/assets/js/188.7b004fea.js"><link rel="prefetch" href="/assets/js/189.599ca2d9.js"><link rel="prefetch" href="/assets/js/19.5740e4d6.js"><link rel="prefetch" href="/assets/js/190.14087c07.js"><link rel="prefetch" href="/assets/js/191.b0f73f6d.js"><link rel="prefetch" href="/assets/js/192.9d171669.js"><link rel="prefetch" href="/assets/js/193.00975585.js"><link rel="prefetch" href="/assets/js/194.2c7c43b4.js"><link rel="prefetch" href="/assets/js/195.ff126254.js"><link rel="prefetch" href="/assets/js/196.6546ae1c.js"><link rel="prefetch" href="/assets/js/197.eedb67bb.js"><link rel="prefetch" href="/assets/js/198.acdcc22c.js"><link rel="prefetch" href="/assets/js/199.7993a6b2.js"><link rel="prefetch" href="/assets/js/20.8885a4fa.js"><link rel="prefetch" href="/assets/js/200.52f08765.js"><link rel="prefetch" href="/assets/js/201.b85ab10b.js"><link rel="prefetch" href="/assets/js/202.ccec1c85.js"><link rel="prefetch" href="/assets/js/204.f28b803b.js"><link rel="prefetch" href="/assets/js/205.c51c53fd.js"><link rel="prefetch" href="/assets/js/206.ba0aa8f6.js"><link rel="prefetch" href="/assets/js/207.0dce311a.js"><link rel="prefetch" href="/assets/js/208.0ea629a6.js"><link rel="prefetch" href="/assets/js/209.f48c3e71.js"><link rel="prefetch" href="/assets/js/21.0bb62db4.js"><link rel="prefetch" href="/assets/js/210.689db8f2.js"><link rel="prefetch" href="/assets/js/211.72bc0f1f.js"><link rel="prefetch" href="/assets/js/212.456135bd.js"><link rel="prefetch" href="/assets/js/213.d0ea50fc.js"><link rel="prefetch" href="/assets/js/214.1400da91.js"><link rel="prefetch" href="/assets/js/215.aeef3e5d.js"><link rel="prefetch" href="/assets/js/216.a60215af.js"><link rel="prefetch" href="/assets/js/217.d6cd8b69.js"><link rel="prefetch" href="/assets/js/218.1bd500fc.js"><link rel="prefetch" href="/assets/js/219.20faf611.js"><link rel="prefetch" href="/assets/js/22.3e8347a6.js"><link rel="prefetch" href="/assets/js/220.6714179b.js"><link rel="prefetch" href="/assets/js/221.fb5b643d.js"><link rel="prefetch" href="/assets/js/222.d96272e5.js"><link rel="prefetch" href="/assets/js/223.4cb7dc3d.js"><link rel="prefetch" href="/assets/js/224.500d94cc.js"><link rel="prefetch" href="/assets/js/225.d006c34e.js"><link rel="prefetch" href="/assets/js/226.73612150.js"><link rel="prefetch" href="/assets/js/227.b02db9d1.js"><link rel="prefetch" href="/assets/js/228.aad43ff2.js"><link rel="prefetch" href="/assets/js/229.65340802.js"><link rel="prefetch" href="/assets/js/23.ceb5a5ff.js"><link rel="prefetch" href="/assets/js/230.97cab104.js"><link rel="prefetch" href="/assets/js/231.8415349a.js"><link rel="prefetch" href="/assets/js/232.db6d2697.js"><link rel="prefetch" href="/assets/js/233.723d05b1.js"><link rel="prefetch" href="/assets/js/234.26ed5e94.js"><link rel="prefetch" href="/assets/js/235.a586122b.js"><link rel="prefetch" href="/assets/js/236.f802bda8.js"><link rel="prefetch" href="/assets/js/237.cc8767ad.js"><link rel="prefetch" href="/assets/js/238.6485459e.js"><link rel="prefetch" href="/assets/js/239.9fbf3a55.js"><link rel="prefetch" href="/assets/js/24.07267ac6.js"><link rel="prefetch" href="/assets/js/240.1188f244.js"><link rel="prefetch" href="/assets/js/241.cbfb154d.js"><link rel="prefetch" href="/assets/js/242.352cea5a.js"><link rel="prefetch" href="/assets/js/243.07947e1c.js"><link rel="prefetch" href="/assets/js/244.f5b26fa9.js"><link rel="prefetch" href="/assets/js/245.c6030e32.js"><link rel="prefetch" href="/assets/js/246.d3fe99f7.js"><link rel="prefetch" href="/assets/js/247.185ae95d.js"><link rel="prefetch" href="/assets/js/248.a5f1548c.js"><link rel="prefetch" href="/assets/js/249.19691113.js"><link rel="prefetch" href="/assets/js/25.15e1f641.js"><link rel="prefetch" href="/assets/js/250.72fa1d33.js"><link rel="prefetch" href="/assets/js/251.bedd56f7.js"><link rel="prefetch" href="/assets/js/252.32bbcc8b.js"><link rel="prefetch" href="/assets/js/253.b59e5846.js"><link rel="prefetch" href="/assets/js/254.c0e37e1a.js"><link rel="prefetch" href="/assets/js/255.850da3cc.js"><link rel="prefetch" href="/assets/js/256.952d9817.js"><link rel="prefetch" href="/assets/js/257.88667bb8.js"><link rel="prefetch" href="/assets/js/258.c5873c28.js"><link rel="prefetch" href="/assets/js/259.6ae1dcbc.js"><link rel="prefetch" href="/assets/js/26.35b2bbdc.js"><link rel="prefetch" href="/assets/js/260.cb940cc3.js"><link rel="prefetch" href="/assets/js/261.0686c3e9.js"><link rel="prefetch" href="/assets/js/262.d0719839.js"><link rel="prefetch" href="/assets/js/263.ae83ebc1.js"><link rel="prefetch" href="/assets/js/264.209ad8a3.js"><link rel="prefetch" href="/assets/js/265.be8d1ee8.js"><link rel="prefetch" href="/assets/js/266.c51bceaa.js"><link rel="prefetch" href="/assets/js/267.fe8af48a.js"><link rel="prefetch" href="/assets/js/268.e18ed861.js"><link rel="prefetch" href="/assets/js/269.7126031e.js"><link rel="prefetch" href="/assets/js/27.270fcb06.js"><link rel="prefetch" href="/assets/js/270.89ead106.js"><link rel="prefetch" href="/assets/js/271.0643d07a.js"><link rel="prefetch" href="/assets/js/272.32a8e4b0.js"><link rel="prefetch" href="/assets/js/273.9881da47.js"><link rel="prefetch" href="/assets/js/274.2de022ea.js"><link rel="prefetch" href="/assets/js/275.d9a4fe99.js"><link rel="prefetch" href="/assets/js/276.d33de2e9.js"><link rel="prefetch" href="/assets/js/277.1ec367ab.js"><link rel="prefetch" href="/assets/js/278.66ab7c11.js"><link rel="prefetch" href="/assets/js/279.ff51cd15.js"><link rel="prefetch" href="/assets/js/28.ef3f6db2.js"><link rel="prefetch" href="/assets/js/280.ef45ed5f.js"><link rel="prefetch" href="/assets/js/281.87f26b81.js"><link rel="prefetch" href="/assets/js/282.c8ef594b.js"><link rel="prefetch" href="/assets/js/283.15643091.js"><link rel="prefetch" href="/assets/js/284.c4f25b2e.js"><link rel="prefetch" href="/assets/js/285.2d16e4b6.js"><link rel="prefetch" href="/assets/js/286.44eba266.js"><link rel="prefetch" href="/assets/js/287.7613e62f.js"><link rel="prefetch" href="/assets/js/288.b9546d55.js"><link rel="prefetch" href="/assets/js/289.125f85d8.js"><link rel="prefetch" href="/assets/js/29.177558be.js"><link rel="prefetch" href="/assets/js/290.db375797.js"><link rel="prefetch" href="/assets/js/291.90946626.js"><link rel="prefetch" href="/assets/js/292.a4524678.js"><link rel="prefetch" href="/assets/js/293.3ed9b083.js"><link rel="prefetch" href="/assets/js/294.d6c14116.js"><link rel="prefetch" href="/assets/js/295.2b485032.js"><link rel="prefetch" href="/assets/js/296.29d9aa0f.js"><link rel="prefetch" href="/assets/js/297.bfd72435.js"><link rel="prefetch" href="/assets/js/298.fc056989.js"><link rel="prefetch" href="/assets/js/299.0a3f258e.js"><link rel="prefetch" href="/assets/js/3.4dc033c7.js"><link rel="prefetch" href="/assets/js/30.248a229d.js"><link rel="prefetch" href="/assets/js/300.d064d776.js"><link rel="prefetch" href="/assets/js/301.d95b9fc0.js"><link rel="prefetch" href="/assets/js/302.1afa637a.js"><link rel="prefetch" href="/assets/js/303.231beaa8.js"><link rel="prefetch" href="/assets/js/304.05df35d9.js"><link rel="prefetch" href="/assets/js/305.f2d83cf9.js"><link rel="prefetch" href="/assets/js/306.d54f5e5e.js"><link rel="prefetch" href="/assets/js/307.d5df9000.js"><link rel="prefetch" href="/assets/js/308.ef2f52b3.js"><link rel="prefetch" href="/assets/js/309.d1f13319.js"><link rel="prefetch" href="/assets/js/31.32a62b91.js"><link rel="prefetch" href="/assets/js/310.30b84be3.js"><link rel="prefetch" href="/assets/js/311.d79e3145.js"><link rel="prefetch" href="/assets/js/312.58e24f19.js"><link rel="prefetch" href="/assets/js/313.9809a122.js"><link rel="prefetch" href="/assets/js/314.e92e41b1.js"><link rel="prefetch" href="/assets/js/315.8c2fc1d4.js"><link rel="prefetch" href="/assets/js/316.a0904343.js"><link rel="prefetch" href="/assets/js/317.18e42b54.js"><link rel="prefetch" href="/assets/js/318.6b051d27.js"><link rel="prefetch" href="/assets/js/319.513b0197.js"><link rel="prefetch" href="/assets/js/32.23b75afc.js"><link rel="prefetch" href="/assets/js/320.ae91bc36.js"><link rel="prefetch" href="/assets/js/321.a194efea.js"><link rel="prefetch" href="/assets/js/322.8273020e.js"><link rel="prefetch" href="/assets/js/323.d332e08f.js"><link rel="prefetch" href="/assets/js/324.ed867b64.js"><link rel="prefetch" href="/assets/js/325.c43ccf9a.js"><link rel="prefetch" href="/assets/js/326.9497d879.js"><link rel="prefetch" href="/assets/js/327.7f095e40.js"><link rel="prefetch" href="/assets/js/328.cb5c5847.js"><link rel="prefetch" href="/assets/js/329.d36b59f3.js"><link rel="prefetch" href="/assets/js/33.b258b779.js"><link rel="prefetch" href="/assets/js/330.b1a092b9.js"><link rel="prefetch" href="/assets/js/331.ff86566f.js"><link rel="prefetch" href="/assets/js/332.0daafa9f.js"><link rel="prefetch" href="/assets/js/333.b7e50524.js"><link rel="prefetch" href="/assets/js/334.7dcf9f0b.js"><link rel="prefetch" href="/assets/js/335.862c410a.js"><link rel="prefetch" href="/assets/js/336.c6384990.js"><link rel="prefetch" href="/assets/js/337.ab9d5e52.js"><link rel="prefetch" href="/assets/js/338.598ae59e.js"><link rel="prefetch" href="/assets/js/339.9b810ff8.js"><link rel="prefetch" href="/assets/js/34.3bd60f1f.js"><link rel="prefetch" href="/assets/js/340.5609a53c.js"><link rel="prefetch" href="/assets/js/341.969d335a.js"><link rel="prefetch" href="/assets/js/342.43f85dba.js"><link rel="prefetch" href="/assets/js/343.47280ef9.js"><link rel="prefetch" href="/assets/js/344.346ae5fc.js"><link rel="prefetch" href="/assets/js/345.32166361.js"><link rel="prefetch" href="/assets/js/346.86ff128b.js"><link rel="prefetch" href="/assets/js/347.3c5421fe.js"><link rel="prefetch" href="/assets/js/348.95910300.js"><link rel="prefetch" href="/assets/js/349.004158d8.js"><link rel="prefetch" href="/assets/js/35.18e8f66a.js"><link rel="prefetch" href="/assets/js/350.e10b195b.js"><link rel="prefetch" href="/assets/js/351.12f89875.js"><link rel="prefetch" href="/assets/js/352.83957394.js"><link rel="prefetch" href="/assets/js/353.475971b9.js"><link rel="prefetch" href="/assets/js/354.8af7b26b.js"><link rel="prefetch" href="/assets/js/355.85925e24.js"><link rel="prefetch" href="/assets/js/356.1d77cf9c.js"><link rel="prefetch" href="/assets/js/357.b467d481.js"><link rel="prefetch" href="/assets/js/358.ac96f32d.js"><link rel="prefetch" href="/assets/js/359.e048bd10.js"><link rel="prefetch" href="/assets/js/36.a7ae257c.js"><link rel="prefetch" href="/assets/js/360.e9b45545.js"><link rel="prefetch" href="/assets/js/361.ad1bb45b.js"><link rel="prefetch" href="/assets/js/362.4e24a30b.js"><link rel="prefetch" href="/assets/js/363.64f7dad5.js"><link rel="prefetch" href="/assets/js/364.d9e3ebc2.js"><link rel="prefetch" href="/assets/js/365.330e3086.js"><link rel="prefetch" href="/assets/js/366.a6c0afb3.js"><link rel="prefetch" href="/assets/js/367.ffcefa40.js"><link rel="prefetch" href="/assets/js/368.664c8e4d.js"><link rel="prefetch" href="/assets/js/369.67da2dd2.js"><link rel="prefetch" href="/assets/js/37.d709f9a9.js"><link rel="prefetch" href="/assets/js/370.b1791970.js"><link rel="prefetch" href="/assets/js/371.743a461a.js"><link rel="prefetch" href="/assets/js/372.7703ef1b.js"><link rel="prefetch" href="/assets/js/373.17de31f6.js"><link rel="prefetch" href="/assets/js/374.e508be9e.js"><link rel="prefetch" href="/assets/js/375.6e2e9fe3.js"><link rel="prefetch" href="/assets/js/376.8ca3511a.js"><link rel="prefetch" href="/assets/js/377.bfcee39c.js"><link rel="prefetch" href="/assets/js/378.21852b78.js"><link rel="prefetch" href="/assets/js/379.9649c307.js"><link rel="prefetch" href="/assets/js/38.68ca920e.js"><link rel="prefetch" href="/assets/js/380.dadb4418.js"><link rel="prefetch" href="/assets/js/381.a03c993d.js"><link rel="prefetch" href="/assets/js/382.bb7c22c1.js"><link rel="prefetch" href="/assets/js/383.bd68b2e5.js"><link rel="prefetch" href="/assets/js/384.f6dc7457.js"><link rel="prefetch" href="/assets/js/385.14287a91.js"><link rel="prefetch" href="/assets/js/386.a6284ac2.js"><link rel="prefetch" href="/assets/js/387.c51f147a.js"><link rel="prefetch" href="/assets/js/388.06d9651e.js"><link rel="prefetch" href="/assets/js/389.2d85d927.js"><link rel="prefetch" href="/assets/js/39.de850db9.js"><link rel="prefetch" href="/assets/js/390.2397b3e0.js"><link rel="prefetch" href="/assets/js/391.8413aaaf.js"><link rel="prefetch" href="/assets/js/392.00eecaa4.js"><link rel="prefetch" href="/assets/js/393.351dd3fd.js"><link rel="prefetch" href="/assets/js/394.d2cc4a70.js"><link rel="prefetch" href="/assets/js/395.abee64bf.js"><link rel="prefetch" href="/assets/js/396.bc265e6a.js"><link rel="prefetch" href="/assets/js/397.e4a96944.js"><link rel="prefetch" href="/assets/js/398.f0d26b29.js"><link rel="prefetch" href="/assets/js/399.e77c3ddc.js"><link rel="prefetch" href="/assets/js/4.2f502b73.js"><link rel="prefetch" href="/assets/js/40.91635261.js"><link rel="prefetch" href="/assets/js/400.c7eac401.js"><link rel="prefetch" href="/assets/js/401.06092d16.js"><link rel="prefetch" href="/assets/js/402.4e08e496.js"><link rel="prefetch" href="/assets/js/403.deba4c77.js"><link rel="prefetch" href="/assets/js/404.9100e4df.js"><link rel="prefetch" href="/assets/js/405.e9f451e2.js"><link rel="prefetch" href="/assets/js/406.a0da4aa4.js"><link rel="prefetch" href="/assets/js/407.58b2b123.js"><link rel="prefetch" href="/assets/js/408.eb2cde2d.js"><link rel="prefetch" href="/assets/js/409.9041f749.js"><link rel="prefetch" href="/assets/js/41.169a3cfc.js"><link rel="prefetch" href="/assets/js/410.c12f3710.js"><link rel="prefetch" href="/assets/js/411.452cda45.js"><link rel="prefetch" href="/assets/js/412.8691317a.js"><link rel="prefetch" href="/assets/js/413.25a68f21.js"><link rel="prefetch" href="/assets/js/414.7a9699d8.js"><link rel="prefetch" href="/assets/js/415.6e8cdaff.js"><link rel="prefetch" href="/assets/js/416.e8a86529.js"><link rel="prefetch" href="/assets/js/417.28330bde.js"><link rel="prefetch" href="/assets/js/418.2fed8e17.js"><link rel="prefetch" href="/assets/js/419.773032f4.js"><link rel="prefetch" href="/assets/js/42.e17cd061.js"><link rel="prefetch" href="/assets/js/420.56681228.js"><link rel="prefetch" href="/assets/js/421.0d170e13.js"><link rel="prefetch" href="/assets/js/422.fc8c2a11.js"><link rel="prefetch" href="/assets/js/423.e34ea6a6.js"><link rel="prefetch" href="/assets/js/424.20fe8748.js"><link rel="prefetch" href="/assets/js/425.f001b7cd.js"><link rel="prefetch" href="/assets/js/426.a91230ef.js"><link rel="prefetch" href="/assets/js/427.c6c9fe8d.js"><link rel="prefetch" href="/assets/js/428.9d4f5e41.js"><link rel="prefetch" href="/assets/js/429.c81cfd3f.js"><link rel="prefetch" href="/assets/js/43.f88aa667.js"><link rel="prefetch" href="/assets/js/430.eb61372f.js"><link rel="prefetch" href="/assets/js/431.4a25365a.js"><link rel="prefetch" href="/assets/js/432.42fc1bbe.js"><link rel="prefetch" href="/assets/js/433.8e9ac9f0.js"><link rel="prefetch" href="/assets/js/434.fdd0b160.js"><link rel="prefetch" href="/assets/js/435.d6cbac31.js"><link rel="prefetch" href="/assets/js/436.17750ba2.js"><link rel="prefetch" href="/assets/js/437.a1468099.js"><link rel="prefetch" href="/assets/js/438.ac6a45c2.js"><link rel="prefetch" href="/assets/js/439.242ae27a.js"><link rel="prefetch" href="/assets/js/44.3f36e228.js"><link rel="prefetch" href="/assets/js/440.b80b520c.js"><link rel="prefetch" href="/assets/js/441.e51a4bbb.js"><link rel="prefetch" href="/assets/js/442.ab0b3eda.js"><link rel="prefetch" href="/assets/js/443.47e44250.js"><link rel="prefetch" href="/assets/js/444.54c3b425.js"><link rel="prefetch" href="/assets/js/445.e006c12e.js"><link rel="prefetch" href="/assets/js/446.f2b79730.js"><link rel="prefetch" href="/assets/js/447.2509a397.js"><link rel="prefetch" href="/assets/js/448.b7d69dfc.js"><link rel="prefetch" href="/assets/js/449.8a575d9b.js"><link rel="prefetch" href="/assets/js/45.be1455b1.js"><link rel="prefetch" href="/assets/js/450.ad421aeb.js"><link rel="prefetch" href="/assets/js/451.f09912ae.js"><link rel="prefetch" href="/assets/js/452.f528c4ce.js"><link rel="prefetch" href="/assets/js/453.fc4dc0f9.js"><link rel="prefetch" href="/assets/js/454.733c315c.js"><link rel="prefetch" href="/assets/js/455.44fe35b1.js"><link rel="prefetch" href="/assets/js/456.7f650035.js"><link rel="prefetch" href="/assets/js/457.77ebc183.js"><link rel="prefetch" href="/assets/js/458.133078f4.js"><link rel="prefetch" href="/assets/js/459.33728b5e.js"><link rel="prefetch" href="/assets/js/46.5ad74cb5.js"><link rel="prefetch" href="/assets/js/460.6946f564.js"><link rel="prefetch" href="/assets/js/461.6f906c5c.js"><link rel="prefetch" href="/assets/js/462.26eca27e.js"><link rel="prefetch" href="/assets/js/463.e02e5f65.js"><link rel="prefetch" href="/assets/js/464.0df25c63.js"><link rel="prefetch" href="/assets/js/465.80cd249e.js"><link rel="prefetch" href="/assets/js/466.a0921e86.js"><link rel="prefetch" href="/assets/js/467.1bec2b47.js"><link rel="prefetch" href="/assets/js/468.b6fa37c1.js"><link rel="prefetch" href="/assets/js/469.a1d2487e.js"><link rel="prefetch" href="/assets/js/47.03df5d0a.js"><link rel="prefetch" href="/assets/js/470.36a4b9c8.js"><link rel="prefetch" href="/assets/js/471.28895273.js"><link rel="prefetch" href="/assets/js/472.b9fe392f.js"><link rel="prefetch" href="/assets/js/473.a2835d9c.js"><link rel="prefetch" href="/assets/js/474.cd57b37d.js"><link rel="prefetch" href="/assets/js/475.8d5a9792.js"><link rel="prefetch" href="/assets/js/476.f7f3781c.js"><link rel="prefetch" href="/assets/js/477.9b710b04.js"><link rel="prefetch" href="/assets/js/478.46d66687.js"><link rel="prefetch" href="/assets/js/479.e7444705.js"><link rel="prefetch" href="/assets/js/48.48f286ba.js"><link rel="prefetch" href="/assets/js/480.da2b750a.js"><link rel="prefetch" href="/assets/js/481.838a8e04.js"><link rel="prefetch" href="/assets/js/482.02bf8041.js"><link rel="prefetch" href="/assets/js/483.bb29ef2f.js"><link rel="prefetch" href="/assets/js/484.aebb68bd.js"><link rel="prefetch" href="/assets/js/485.a66ab41b.js"><link rel="prefetch" href="/assets/js/486.8df516fb.js"><link rel="prefetch" href="/assets/js/487.86d28130.js"><link rel="prefetch" href="/assets/js/488.0863da70.js"><link rel="prefetch" href="/assets/js/489.5d4d9e88.js"><link rel="prefetch" href="/assets/js/49.1ca52d11.js"><link rel="prefetch" href="/assets/js/490.3fd65d85.js"><link rel="prefetch" href="/assets/js/491.ae3a2f87.js"><link rel="prefetch" href="/assets/js/492.6f54679b.js"><link rel="prefetch" href="/assets/js/493.a594b1f4.js"><link rel="prefetch" href="/assets/js/494.4f03fae1.js"><link rel="prefetch" href="/assets/js/495.ae50b66b.js"><link rel="prefetch" href="/assets/js/496.bc92d835.js"><link rel="prefetch" href="/assets/js/497.eac65251.js"><link rel="prefetch" href="/assets/js/498.1d726726.js"><link rel="prefetch" href="/assets/js/499.01e4f7d1.js"><link rel="prefetch" href="/assets/js/5.7b1f056c.js"><link rel="prefetch" href="/assets/js/50.73732fe2.js"><link rel="prefetch" href="/assets/js/500.062ade4e.js"><link rel="prefetch" href="/assets/js/501.e6a711dc.js"><link rel="prefetch" href="/assets/js/502.c79e28e2.js"><link rel="prefetch" href="/assets/js/503.bf97bce9.js"><link rel="prefetch" href="/assets/js/504.b2784ef0.js"><link rel="prefetch" href="/assets/js/505.0767ba54.js"><link rel="prefetch" href="/assets/js/506.8ae14637.js"><link rel="prefetch" href="/assets/js/507.003e2349.js"><link rel="prefetch" href="/assets/js/508.ecb5e6bd.js"><link rel="prefetch" href="/assets/js/509.b644f44a.js"><link rel="prefetch" href="/assets/js/51.bed7cf61.js"><link rel="prefetch" href="/assets/js/510.b660946f.js"><link rel="prefetch" href="/assets/js/511.cb186c8f.js"><link rel="prefetch" href="/assets/js/512.d176170f.js"><link rel="prefetch" href="/assets/js/513.18a1afa5.js"><link rel="prefetch" href="/assets/js/514.4a33e931.js"><link rel="prefetch" href="/assets/js/515.8496bd4d.js"><link rel="prefetch" href="/assets/js/516.529b9476.js"><link rel="prefetch" href="/assets/js/517.289738f1.js"><link rel="prefetch" href="/assets/js/518.eda39556.js"><link rel="prefetch" href="/assets/js/519.85b42de5.js"><link rel="prefetch" href="/assets/js/52.22a7da62.js"><link rel="prefetch" href="/assets/js/520.8b531775.js"><link rel="prefetch" href="/assets/js/521.8e4b66fb.js"><link rel="prefetch" href="/assets/js/522.050bfc55.js"><link rel="prefetch" href="/assets/js/523.e973f1e0.js"><link rel="prefetch" href="/assets/js/524.fd160738.js"><link rel="prefetch" href="/assets/js/525.5a4bc307.js"><link rel="prefetch" href="/assets/js/526.361bc4fa.js"><link rel="prefetch" href="/assets/js/527.06ee9d73.js"><link rel="prefetch" href="/assets/js/528.22d9b118.js"><link rel="prefetch" href="/assets/js/529.b7592c16.js"><link rel="prefetch" href="/assets/js/53.767f3bbf.js"><link rel="prefetch" href="/assets/js/530.ad96d564.js"><link rel="prefetch" href="/assets/js/531.61905243.js"><link rel="prefetch" href="/assets/js/532.11aebf61.js"><link rel="prefetch" href="/assets/js/533.0cddb226.js"><link rel="prefetch" href="/assets/js/534.d1c9cc36.js"><link rel="prefetch" href="/assets/js/54.d1f9eec8.js"><link rel="prefetch" href="/assets/js/55.aa90e812.js"><link rel="prefetch" href="/assets/js/56.4d7f81f2.js"><link rel="prefetch" href="/assets/js/57.3c540e8d.js"><link rel="prefetch" href="/assets/js/58.fc1c23f2.js"><link rel="prefetch" href="/assets/js/59.c7a7a4c0.js"><link rel="prefetch" href="/assets/js/6.056886f1.js"><link rel="prefetch" href="/assets/js/60.40e590ae.js"><link rel="prefetch" href="/assets/js/61.e400b323.js"><link rel="prefetch" href="/assets/js/62.bbb30ef1.js"><link rel="prefetch" href="/assets/js/63.c31cd2bb.js"><link rel="prefetch" href="/assets/js/64.62321188.js"><link rel="prefetch" href="/assets/js/65.44adc2b3.js"><link rel="prefetch" href="/assets/js/66.b5740d4f.js"><link rel="prefetch" href="/assets/js/67.76c3624c.js"><link rel="prefetch" href="/assets/js/68.6dd982d4.js"><link rel="prefetch" href="/assets/js/69.eb1390ec.js"><link rel="prefetch" href="/assets/js/7.a96cecf9.js"><link rel="prefetch" href="/assets/js/70.8c882bdd.js"><link rel="prefetch" href="/assets/js/71.001c968a.js"><link rel="prefetch" href="/assets/js/72.ae4ca075.js"><link rel="prefetch" href="/assets/js/73.d6ae6a27.js"><link rel="prefetch" href="/assets/js/74.fba60e37.js"><link rel="prefetch" href="/assets/js/75.0b1bf7bf.js"><link rel="prefetch" href="/assets/js/76.ee19d90e.js"><link rel="prefetch" href="/assets/js/77.fe8ac5f0.js"><link rel="prefetch" href="/assets/js/78.ae09432e.js"><link rel="prefetch" href="/assets/js/79.c1b10e2d.js"><link rel="prefetch" href="/assets/js/80.ae809538.js"><link rel="prefetch" href="/assets/js/81.ca11b4c7.js"><link rel="prefetch" href="/assets/js/82.308b98e4.js"><link rel="prefetch" href="/assets/js/83.355d9dde.js"><link rel="prefetch" href="/assets/js/84.a2b61d48.js"><link rel="prefetch" href="/assets/js/85.cf992fda.js"><link rel="prefetch" href="/assets/js/86.f547c7ea.js"><link rel="prefetch" href="/assets/js/87.2b02746a.js"><link rel="prefetch" href="/assets/js/88.e939aad5.js"><link rel="prefetch" href="/assets/js/89.b000c42a.js"><link rel="prefetch" href="/assets/js/90.dadef001.js"><link rel="prefetch" href="/assets/js/91.c0fe2e32.js"><link rel="prefetch" href="/assets/js/92.e09650b9.js"><link rel="prefetch" href="/assets/js/93.427c7280.js"><link rel="prefetch" href="/assets/js/94.90fc5f58.js"><link rel="prefetch" href="/assets/js/95.13d42b3a.js"><link rel="prefetch" href="/assets/js/96.d0a2ea8c.js"><link rel="prefetch" href="/assets/js/97.cc9a0eda.js"><link rel="prefetch" href="/assets/js/98.3c9f1b7e.js"><link rel="prefetch" href="/assets/js/99.0420dcbc.js"><link rel="prefetch" href="/assets/js/vendors~docsearch.33b2b47d.js">
    <link rel="stylesheet" href="/assets/css/0.styles.40c15e22.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><img src="/logo.png" alt="鱼皮的编程宝典" class="logo"> <span class="site-name can-hide">鱼皮的编程宝典</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/学习路线/" class="nav-link">
  学习路线
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="自学之路" class="dropdown-title"><span class="title">自学之路</span> <span class="arrow down"></span></button> <button type="button" aria-label="自学之路" class="mobile-dropdown-title"><span class="title">自学之路</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/自学之路/#大学经历" class="nav-link">
  大学经历
</a></li><li class="dropdown-item"><!----> <a href="/自学之路/#求职经历" class="nav-link">
  求职经历
</a></li><li class="dropdown-item"><!----> <a href="/自学之路/#职场工作" class="nav-link">
  职场工作
</a></li><li class="dropdown-item"><!----> <a href="/自学之路/#创作经历" class="nav-link">
  创作经历
</a></li><li class="dropdown-item"><!----> <a href="/自学之路/#创业经历" class="nav-link">
  创业经历
</a></li><li class="dropdown-item"><!----> <a href="/自学之路/#生活日常" class="nav-link">
  生活日常
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="编程分享" class="dropdown-title"><span class="title">编程分享</span> <span class="arrow down"></span></button> <button type="button" aria-label="编程分享" class="mobile-dropdown-title"><span class="title">编程分享</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/编程分享/#入门必看-学习路线" class="nav-link">
  入门必看-学习路线
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#学习指南" class="nav-link">
  学习指南
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#开发经验" class="nav-link">
  开发经验
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#求职经验" class="nav-link">
  求职经验
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#职场经验" class="nav-link">
  职场经验
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#技术分享" class="nav-link">
  技术分享
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#实战教程" class="nav-link">
  实战教程
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#其他" class="nav-link">
  其他
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#📚-项目教程" class="nav-link">
  项目教程
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#个人作品" class="nav-link">
  个人作品
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#🎁-编程资源" class="nav-link">
  编程资源
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#🌐-科技科普" class="nav-link">
  科技科普
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="项目实战" class="dropdown-title"><span class="title">项目实战</span> <span class="arrow down"></span></button> <button type="button" aria-label="项目实战" class="mobile-dropdown-title"><span class="title">项目实战</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/项目实战/OJ 判题系统.html" class="nav-link">
  OJ 判题系统
</a></li><li class="dropdown-item"><!----> <a href="/项目实战/智能 BI 平台.html" class="nav-link">
  智能 BI 平台
</a></li><li class="dropdown-item"><!----> <a href="/项目实战/聚合搜索平台.html" class="nav-link">
  聚合搜索平台
</a></li><li class="dropdown-item"><!----> <a href="/项目实战/API 开放平台.html" class="nav-link">
  API 开放平台
</a></li><li class="dropdown-item"><!----> <a href="/项目实战/伙伴匹配系统.html" class="nav-link">
  伙伴匹配系统
</a></li><li class="dropdown-item"><!----> <a href="/项目实战/用户中心项目.html" class="nav-link">
  用户中心项目
</a></li><li class="dropdown-item"><!----> <a href="/项目实战/Java 后端万用项目模板.html" class="nav-link">
  Java 后端万用项目模板
</a></li></ul></div></div><div class="nav-item"><a href="/知识碎片/" class="nav-link">
  知识碎片
</a></div><div class="nav-item"><a href="/编程导航/" class="nav-link">
  🔥 编程导航
</a></div><div class="nav-item"><a href="/产品服务/" class="nav-link">
  产品服务
</a></div><div class="nav-item"><a href="/作者/" class="nav-link">
  作者
</a></div> <a href="https://github.com/liyupi/codefather" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/学习路线/" class="nav-link">
  学习路线
</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="自学之路" class="dropdown-title"><span class="title">自学之路</span> <span class="arrow down"></span></button> <button type="button" aria-label="自学之路" class="mobile-dropdown-title"><span class="title">自学之路</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/自学之路/#大学经历" class="nav-link">
  大学经历
</a></li><li class="dropdown-item"><!----> <a href="/自学之路/#求职经历" class="nav-link">
  求职经历
</a></li><li class="dropdown-item"><!----> <a href="/自学之路/#职场工作" class="nav-link">
  职场工作
</a></li><li class="dropdown-item"><!----> <a href="/自学之路/#创作经历" class="nav-link">
  创作经历
</a></li><li class="dropdown-item"><!----> <a href="/自学之路/#创业经历" class="nav-link">
  创业经历
</a></li><li class="dropdown-item"><!----> <a href="/自学之路/#生活日常" class="nav-link">
  生活日常
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="编程分享" class="dropdown-title"><span class="title">编程分享</span> <span class="arrow down"></span></button> <button type="button" aria-label="编程分享" class="mobile-dropdown-title"><span class="title">编程分享</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/编程分享/#入门必看-学习路线" class="nav-link">
  入门必看-学习路线
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#学习指南" class="nav-link">
  学习指南
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#开发经验" class="nav-link">
  开发经验
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#求职经验" class="nav-link">
  求职经验
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#职场经验" class="nav-link">
  职场经验
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#技术分享" class="nav-link">
  技术分享
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#实战教程" class="nav-link">
  实战教程
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#其他" class="nav-link">
  其他
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#📚-项目教程" class="nav-link">
  项目教程
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#个人作品" class="nav-link">
  个人作品
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#🎁-编程资源" class="nav-link">
  编程资源
</a></li><li class="dropdown-item"><!----> <a href="/编程分享/#🌐-科技科普" class="nav-link">
  科技科普
</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="项目实战" class="dropdown-title"><span class="title">项目实战</span> <span class="arrow down"></span></button> <button type="button" aria-label="项目实战" class="mobile-dropdown-title"><span class="title">项目实战</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/项目实战/OJ 判题系统.html" class="nav-link">
  OJ 判题系统
</a></li><li class="dropdown-item"><!----> <a href="/项目实战/智能 BI 平台.html" class="nav-link">
  智能 BI 平台
</a></li><li class="dropdown-item"><!----> <a href="/项目实战/聚合搜索平台.html" class="nav-link">
  聚合搜索平台
</a></li><li class="dropdown-item"><!----> <a href="/项目实战/API 开放平台.html" class="nav-link">
  API 开放平台
</a></li><li class="dropdown-item"><!----> <a href="/项目实战/伙伴匹配系统.html" class="nav-link">
  伙伴匹配系统
</a></li><li class="dropdown-item"><!----> <a href="/项目实战/用户中心项目.html" class="nav-link">
  用户中心项目
</a></li><li class="dropdown-item"><!----> <a href="/项目实战/Java 后端万用项目模板.html" class="nav-link">
  Java 后端万用项目模板
</a></li></ul></div></div><div class="nav-item"><a href="/知识碎片/" class="nav-link">
  知识碎片
</a></div><div class="nav-item"><a href="/编程导航/" class="nav-link">
  🔥 编程导航
</a></div><div class="nav-item"><a href="/产品服务/" class="nav-link">
  产品服务
</a></div><div class="nav-item"><a href="/作者/" class="nav-link">
  作者
</a></div> <a href="https://github.com/liyupi/codefather" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav>  <ul class="sidebar-links"><li><a href="/%E7%BC%96%E7%A8%8B%E5%88%86%E4%BA%AB/" class="sidebar-link">入门必看 - 学习路线</a></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>入门必看-学习路线</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>学习指南</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>开发经验</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>求职经验</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>职场经验</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>技术分享</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>实战教程</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>项目教程</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>编程资源</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>科技科普</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>其他</span> <span class="arrow right"></span></p> <!----></section></li></ul> </aside> <main class="page"> <div class="content"><div style="width:100%"><div class="theme-default-content custom-content content__default"><blockquote><p>Linux 虚拟机 + 远程开发保姆级教程，轻松搭建高效开发环境！</p></blockquote> <blockquote><p>本文作者：<a href="https://yuyuanweb.feishu.cn/wiki/Abldw5WkjidySxkKxU2cQdAtnah" target="_blank" rel="noopener noreferrer">程序员鱼皮<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p>本站地址：<a href="https://codefather.cn" target="_blank" rel="noopener noreferrer">https://codefather.cn<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p></blockquote> <p>大家好，我是鱼皮。最近我正在带大家开发 OJ 系统，需要用 <strong>Docker 容器技术</strong> 来实现隔离的代码沙箱。</p> <p>随之而来的是一个难题：很多同学的电脑都是 Windows 的，直接在 Windows 上安装 Docker 容器比较麻烦，需要依赖 WSL（Windows Subsystem for Linux），很容易出现各种报错。</p> <p>比如 WSL 内核版本太低：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934938.png" loading="lazy" class="lazy"></p> <p>缺少 WSL：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934934.png" loading="lazy" class="lazy"></p> <p>所以，我们不妨直接搞一台 Linux 系统的服务器来安装 Docker 吧，不仅不会影响现有的系统，以后开发和部署项目也都会更方便。</p> <p>那么如何拥有一台 Linux 服务器呢？</p> <p>比较常见的有 2 种方式：</p> <ul><li>购买第三方云服务商的云服务器</li> <li>使用虚拟机软件，在自己电脑上额外运行 Linux 系统</li></ul> <p>第一种方式要花钱，就不多说了。本篇文章我会带大家实践第 2 种方式，只需几分钟的时间，手把手带大家在 Windows 上安装 Linux 虚拟机，并且实践 2 种远程开发方法，让大家像使用 Windows 一样轻松地在 Linux 上开发程序。</p> <p>⭐️ 本文对应视频教程：https://www.bilibili.com/video/BV1h94y1k7Jf/（讲解会更细节，建议配合本文使用）</p> <h2 id="一、虚拟机安装"><a href="#一、虚拟机安装" class="header-anchor">#</a> 一、虚拟机安装</h2> <h3 id="_1、下载安装"><a href="#_1、下载安装" class="header-anchor">#</a> 1、下载安装</h3> <p>首先我们要下载虚拟机软件，这里比较推荐 VMware Workstation Player，个人不商业使用是 <strong>免费</strong> 的。</p> <p>直接到 VMware 官网下载：</p> <p>指路：https://www.vmware.com/cn/products/workstation-player.html</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934362.png" loading="lazy" class="lazy"></p> <p>这里有条件的朋友也可以使用 VMware Workstation Pro，功能更全，但是要付费。</p> <p>在官网点击免费下载后，即可进入安装流程。</p> <p>这里要注意勾选 “自动安装 Windows Hypervisor Platform” 和 “将 VMware Workstation 控制台工具添加到系统 PATH” 两个选项：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934651.png" loading="lazy" class="lazy"></p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934344.png" loading="lazy" class="lazy"></p> <p>选择免费、非商用版本：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934937.png" loading="lazy" class="lazy"></p> <p>然后就安装成功了，比起在 Windows 上折腾 WSL，安装虚拟机可方便太多了~</p> <h3 id="_2、安装系统"><a href="#_2、安装系统" class="header-anchor">#</a> 2、安装系统</h3> <p>虚拟机软件安装完成后，我们打开软件，接下来要先新建虚拟机来安装一个 Linux 操作系统：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934477.png" loading="lazy" class="lazy"></p> <p>点击创建新虚拟机，然后它让我们提供一个 Linux 操作系统的镜像：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934323.png" loading="lazy" class="lazy"></p> <p>问题是，Linux 操作系统有很多的发行版，我们安装哪个版本呢？</p> <p>我学生时代的时候，特别喜欢用 CentOS，但可惜的是，CentOS 已经停止维护了。。。</p> <p>所以这里我们选择 Linux Ubuntu 18.04 LTS 版本来给大家演示，有图形界面，会更能照顾到新手同学。</p> <p>Ubuntu 镜像下载：https://releases.ubuntu.com/18.04/</p> <p>拉到底部，找到 <code>.iso</code> 后缀的文件下载即可：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934327.png" loading="lazy" class="lazy"></p> <p>当然，萝卜青菜，各有所爱，会玩 Linux 的同学可以自由选择版本~</p> <p>指定完操作系统后，我们继续新建虚拟机，可以根据实际的电脑情况来自定义虚拟机的硬件。如果你的电脑配置还不错，内存和 CPU 可以分配多一点：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934321.png" loading="lazy" class="lazy"></p> <p>点击完成，然后稍等片刻，系统就安装完成并启动啦！</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934336.png" loading="lazy" class="lazy"></p> <h3 id="_3、修改配置"><a href="#_3、修改配置" class="header-anchor">#</a> 3、修改配置</h3> <p>像购买一台新电脑一样，我们有了新的操作系统后，可以自行修改一些配置，比如修改语言为中文。</p> <h4 id="修改语言为中文"><a href="#修改语言为中文" class="header-anchor">#</a> 修改语言为中文</h4> <p>按 <code>windows</code> 键，弹出功能搜索按钮，输入 &quot;language&quot;，打开 &quot;语言支持&quot;：</p> <p>我这台虚拟机是已经改完语言的，所以截图中已经是中文了</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934166.png" loading="lazy" class="lazy"></p> <p>然后点击添加语言，选择中文简体，并且把汉语拖到语言列表的最上面，最后点击应用到整个系统：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934916.png" loading="lazy" class="lazy"></p> <p>稍等片刻，中文语言包、输入法等内容就安装好了，点击右上角重启虚拟机：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934776.png" loading="lazy" class="lazy"></p> <p>重启后，同样是按 <code>windows</code> 键，弹出功能搜索按钮，输入 &quot;language&quot;，打开 &quot;区域和语言&quot;：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934075.png" loading="lazy" class="lazy"></p> <p>在区域和语言设置中，新增输入源，添加已安装的中文输入法：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934066.png" loading="lazy" class="lazy"></p> <h4 id="修改分辨率"><a href="#修改分辨率" class="header-anchor">#</a> 修改分辨率</h4> <p>用同样的方法，我们可以调整系统的分辨率。</p> <p>先打开显示设置：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934181.png" loading="lazy" class="lazy"></p> <p>然后可以调整分辨率和字体大小：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934860.png" loading="lazy" class="lazy"></p> <h4 id="修改时间"><a href="#修改时间" class="header-anchor">#</a> 修改时间</h4> <p>默认情况下系统的时区可能是有问题的，我们可以打开“日期和时间”设置，选择时区为“中国上海”：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934640.png" loading="lazy" class="lazy"></p> <h3 id="_4、安装软件"><a href="#_4、安装软件" class="header-anchor">#</a> 4、安装软件</h3> <p>基本配置修改完成后，我们就可以给 Linux 系统安装软件并使用了。</p> <p>和其他操作系统一样，Linux Ubuntu 也有自己的应用商店，能够可视化一键安装软件，比如防火墙之类的，适合新手操作：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934990.png" loading="lazy" class="lazy"></p> <p>当然，大家用 Linux 更多地还是要学习它的终端命令行操作，所以这里我们以 Docker 为例，使用命令行来快速安装。</p> <p>按 <code>Ctrl + Alt + T</code> 快速打开终端，输入以下命令来一键安装 Docker：</p> <p>apt 命令是软件包管理工具，能够让我们方便地安装软件</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>sudo apt install docker.io
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>如下图：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934642.png" loading="lazy" class="lazy"></p> <p>安装完成后，输入 <code>docker -v</code> ，查看版本号，如下图：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934646.png" loading="lazy" class="lazy"></p> <p>然后输入 <code>docker run</code> 命令，测试 Docker 能否正常运行：</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>sudo docker run hello-world
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>能看到如下信息，表示 Docker 安装成功：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934721.png" loading="lazy" class="lazy"></p> <p>怎么样，比在 Windows 安装方便多了吧？</p> <h2 id="二、java-远程开发"><a href="#二、java-远程开发" class="header-anchor">#</a> 二、Java 远程开发</h2> <p>有了 Linux 系统后，我们怎么在 Linux 上开发呢？</p> <p>是直接在 Linux 上安装常用的开发工具，然后在虚拟机里编写代码么？</p> <p>No、No、No，这样不仅要改变你原本的编码习惯，还可能会出现卡顿。如果你的项目有的在 Windows、有的在 Linux，需要同时开发的话，来回切换系统可太麻烦了。</p> <p>所以这里我会教大家使用远程开发，直接在自己的 Windows 电脑上操作 Linux 服务器，和之间的开发方式完全一致！</p> <p>两个字：“丝滑”！</p> <p>下面我会以 Java 开发为例，带大家掌握 2 种远程开发的方式：<strong>远程部署</strong> 和 <strong>纯远程开发</strong> ，大家可以根据实际情况选择合适的方式。</p> <h3 id="_1、前置准备"><a href="#_1、前置准备" class="header-anchor">#</a> 1、前置准备</h3> <p>在学习远程开发前，我们要先做一些准备工作。</p> <h4 id="_1-网络连通"><a href="#_1-网络连通" class="header-anchor">#</a> 1）网络连通</h4> <p>要确保我们本地的 Windows 电脑能够连接到 Linux 虚拟机。</p> <p>首先在设置中搜索网络，点击查看网络设置：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934732.png" loading="lazy" class="lazy"></p> <p>获取到虚拟机的 IPv4 地址，这个地址一定要记好了：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934012.png" loading="lazy" class="lazy"></p> <p>在自己的 Windows 电脑上 ping 这个 IP 地址，测试能否 ping 通。</p> <p>如下图，表示网络正常连通：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934731.png" loading="lazy" class="lazy"></p> <h4 id="_2-开启-ssh"><a href="#_2-开启-ssh" class="header-anchor">#</a> 2）开启 SSH</h4> <p>光能 ping 通虚拟机还不够，很多远程开发工具都是通过 SSH 协议连接远程服务器的，所以我们要在 Linux 虚拟机上开启 SSH。</p> <p>在 Linux 虚拟机上打开终端，输入下列命令安装 SSH 服务器：</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>sudo apt-get install openssh-server
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>安装后，输入下列命令检查 SSH 是否已开启：</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>ps -e |grep ssh
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>如下图，则表示 SSH 开启成功：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934784.png" loading="lazy" class="lazy"></p> <p>如果未启动，执行 sudo service ssh start 手动启动服务试试</p> <h4 id="_3-安装-java"><a href="#_3-安装-java" class="header-anchor">#</a> 3）安装 Java</h4> <p>因为我们要演示 Java 远程开发，所以 Java JDK 的安装是必不可少的。</p> <p>Linux 下安装 JDK 还是很方便的，首先打开终端，输入命令来更新软件源信息：</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>sudo apt update
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>然后执行下列命令来安装 Java 8（经典版本）：</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>sudo apt install openjdk-8-jdk
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>安装完成后，输入命令检查 Java 版本：</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>java -version
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>看到如下输出，表示 Java 安装成功：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934981.png" loading="lazy" class="lazy"></p> <h4 id="_4-安装-maven"><a href="#_4-安装-maven" class="header-anchor">#</a> 4）安装 Maven</h4> <p>除了安装 Java 外，我们还要安装 Java 的项目依赖管理工具 Maven，便于接下来我们测试 Spring Boot 项目的远程开发。</p> <p>打开终端，输入如下命令安装 Maven：</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>sudo apt install maven
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>安装完成后，输入命令来查看 Maven 的版本号：</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>mvn -v
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>看到如下输出，表示 Maven 安装成功：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934566.png" loading="lazy" class="lazy"></p> <p>环境准备完毕，接下来开始远程开发之旅~</p> <h3 id="_2、远程部署"><a href="#_2、远程部署" class="header-anchor">#</a> 2、远程部署</h3> <p>第一种远程开发方式是 <strong>远程部署</strong>，就像我们真实做项目时，先在本地用代码编辑器完成开发，再把代码放到 Linux 服务器上去部署一样。远程部署的思路是在本地编写代码，然后把本地的代码文件定期同步到 Linux 服务器，再用本地电脑操作远程服务器完成部署和运行。</p> <p>如下图：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934122.jpeg" loading="lazy" class="lazy"></p> <p>这种方式更多地是为了提高将代码放到服务器部署的效率，不算是真正意义上的远程开发，但可以达到接近的效果。</p> <p>远程开发主要分为 6 个阶段：编码、文件同步、运行、编译构建、部署、调试。接下来让我们以一个最简单干净的 Spring Boot 项目为例，实战上述几个操作。</p> <h4 id="_0-编码"><a href="#_0-编码" class="header-anchor">#</a> 0）编码</h4> <p>假设我们本地已经有了一个示例项目，仅提供一个 checkHealth 接口，用于测试服务能否正常访问，端口为 8080。</p> <p>核心代码如下：</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>@RestController(&quot;/&quot;)
public class MainController {

    @GetMapping(&quot;/health&quot;)
    public String checkHealth() {
        return &quot;ok&quot;;
    }
}
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h4 id="_1-文件同步"><a href="#_1-文件同步" class="header-anchor">#</a> 1）文件同步</h4> <p>打开 JetBrains IDEA 开发工具，点击 Tools =&gt; Development =&gt; Configuration：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934776.png" loading="lazy" class="lazy"></p> <p>进入到如下操作界面，需要先来配置 SSH，和服务器建立连接：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934571.png" loading="lazy" class="lazy"></p> <p>进入 SSH 配置，输入自己实际的服务器 IP！不一定和下图的 IP 地址相同！</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934329.png" loading="lazy" class="lazy"></p> <p>点击测试连接，能看到连接成功的弹窗；如果报错，可能是 IP 地址、用户名或密码输错了。</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934647.png" loading="lazy" class="lazy"></p> <p>回到部署界面，点击 Mappings 来配置路径映射，就是把本地电脑的文件同步到远程服务器的指定路径：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934675.png" loading="lazy" class="lazy"></p> <p>保存，在 IDEA 右侧就能看到我们虚拟机的所有文件列表啦：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934340.png" loading="lazy" class="lazy"></p> <p>然后点击 Tools =&gt; Development =&gt; Automatic Upload，开启自动同步：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934226.png" loading="lazy" class="lazy"></p> <p>现在，尝试在自己电脑的代码文件夹中新建一个文件，该文件就会自动同步到 Linux 虚拟机~</p> <p>但目前如果你删除了自己电脑的文件，Linux 虚拟机的对应文件不会删除，所以我们还要进入 Options 配置：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934991.png" loading="lazy" class="lazy"></p> <p>勾选上文件删除的同步：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934000.png" loading="lazy" class="lazy"></p> <p>至此，你在本地编写的代码都会自动同步到服务器上了。</p> <h4 id="_2-运行项目"><a href="#_2-运行项目" class="header-anchor">#</a> 2）运行项目</h4> <p>可以直接在 IDEA 的终端中快速创建一个能够远程访问远程服务器的终端：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934681.png" loading="lazy" class="lazy"></p> <p>然后使用 <code>cd</code> 命令进入到代码目录：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934935.png" loading="lazy" class="lazy"></p> <p>输入 Maven 命令来运行项目：</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>mvn clean
mvn spring-boot:run
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><p>能够看到项目成功启动：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934979.png" loading="lazy" class="lazy"></p> <p>然后访问远程服务器的接口地址（比如 http://192.168.170.132:8080/health），能够看到如下输出：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934135.png" loading="lazy" class="lazy"></p> <p>表示我们已经能够正常访问到 Linux 服务器上运行的项目了。</p> <p>还可以在 Deployment 界面中配置 web server url，相当于一个快捷访问方式：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934740.png" loading="lazy" class="lazy"></p> <h4 id="_3-构建项目"><a href="#_3-构建项目" class="header-anchor">#</a> 3）构建项目</h4> <p>和上面运行项目的方式相同，在自己的电脑打开终端访问远程虚拟机，然后执行 Maven 打包命令：</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>mvn package
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>看到如下输出，表示打包成功：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934062.png" loading="lazy" class="lazy"></p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934178.png" loading="lazy" class="lazy"></p> <p>然后在服务器上就能看到生成的可执行 jar 包：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934970.png" loading="lazy" class="lazy"></p> <h4 id="_4-部署项目"><a href="#_4-部署项目" class="header-anchor">#</a> 4）部署项目</h4> <p>现在项目可执行 jar 包已经放到了服务器上，我们只需启动即可。</p> <p>输入下列命令，以生产环境运行 jar 包：</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>java -jar /home/yupi/code/target/yuoj-code-sandbox-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>看到如下信息，启动成功：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934272.png" loading="lazy" class="lazy"></p> <h4 id="_5-远程调试"><a href="#_5-远程调试" class="header-anchor">#</a> 5）远程调试</h4> <p>现在程序已经在 Linux 虚拟机上启动了，那么我们如何调试远程的程序呢？比如打断点、查看变量信息等。</p> <p>首先强调一点，远程调试不要乱用，可以在开发时调试，但千万别给线上打断点！影响正常用户的访问。</p> <p>开启远程调试的方法很简单，首先在 IDEA 右上角找到编辑配置：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934281.png" loading="lazy" class="lazy"></p> <p>然后新建一个远程 JVM Debug 配置：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934283.png" loading="lazy" class="lazy"></p> <p>更改配置，修改自己虚拟机的 IP、希望占用的远程调试端口、JDK 版本等，IDEA 会自动生成一段远程调试参数：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934484.png" loading="lazy" class="lazy"></p> <p>在启动项目时，给启动命令追加上述界面生成的 command line 参数，<strong>注意要加到 jar 包路径之前</strong> 。</p> <p>示例命令如下：</p> <div class="language- line-numbers-mode"><pre class="language-text"><code>java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -jar /home/yupi/code/target/yuoj-code-sandbox-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><p>启动项目后，在右上角开启 Debug：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934737.png" loading="lazy" class="lazy"></p> <p>然后给代码打个断点：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934066.png" loading="lazy" class="lazy"></p> <p>再访问对应的端口，可以看到 Debug 已经生效：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934537.png" loading="lazy" class="lazy"></p> <p>现在，你就可以把 Linux 虚拟机当做自己的电脑进行远程开发啦~</p> <h3 id="_3、纯远程开发"><a href="#_3、纯远程开发" class="header-anchor">#</a> 3、纯远程开发</h3> <p>除了上面的方式外，还有一种更简单的远程开发方法。</p> <p>使用 IDEA 自带的远程开发功能，可以直接将本地的编译、构建、调试、运行等工作全部都放在远程服务器上执行！而本地仅运行客户端软件连接服务器，像之前一样编写代码、进行其他开发操作即可。</p> <p>这种方式就很像云游戏，自己的电脑不存放代码、不负责程序的运行，只需要运行一个操作界面即可，而 “脏活累活”都交给服务器。适合本地电脑性能差（服务器性能强）、开发环境多人协作开发、需要统一开发环境的场景。</p> <p>如下图：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934222.jpeg" loading="lazy" class="lazy"></p> <p>这种方式也更简单，进入 IDEA 主页，找到 SSH 选项，点击新建项目：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934016.png" loading="lazy" class="lazy"></p> <p>配置 SSH 连接：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934019.png" loading="lazy" class="lazy"></p> <p>指定远程开发的代码路径：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080935072.png" loading="lazy" class="lazy"></p> <p>首次使用时，需要等待下载 JetBrains Client 客户端：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080934886.png" loading="lazy" class="lazy"></p> <p>服务器上也会自动安装对应的远程开发后端：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080935070.png" loading="lazy" class="lazy"></p> <p>然后进入远程开发：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080935925.png" loading="lazy" class="lazy"></p> <p>打开任务管理器，可以看到 JetBrains 的 client 非常 “轻量”：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080935786.png" loading="lazy" class="lazy"></p> <p>进入客户端界面，软件会自动加载 Maven 项目，但是需要手动指定服务器上已安装的 JDK：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080935669.png" loading="lazy" class="lazy"></p> <p>然后直接以 Debug 模式启动项目：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080935314.png" loading="lazy" class="lazy"></p> <p>还可以配置请求转发，像访问本地服务一样访问远程端口：</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080935307.png" loading="lazy" class="lazy"></p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080935115.png" loading="lazy" class="lazy"></p> <p>接下来访问本机地址 http://127.0.0.1:8080/health，就能够访问到项目啦，而且直接支持 Debug！无须做任何多余的配置！</p> <p><img alt="" data-src="https://pic.yupi.icu/5563/202311080935071.png" loading="lazy" class="lazy"></p> <hr> <p>至此，使用 Linux 虚拟机 + 远程开发的教程就结束了，个人更喜欢第二种远程开发方式，非常简单、而且丝滑，接下来大家就可以愉快地学习 Linux、Docker 等技术啦~</p> <p>原创不易，大家如果学会了的话，希望能点赞收藏支持下 🌹</p></div> <footer class="page-edit" style="margin:0;"><div class="edit-link"><a href="https://github.com/liyupi/codefather/edit/master/编程分享/实战教程/搞台虚拟机玩玩！.md" target="_blank" rel="noopener noreferrer">完善页面</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <div class="last-updated"><span class="prefix">最近更新:</span> <span class="time">11/11/2023, 8:17:47 PM</span></div></footer> <!----></div> <div class="toc-container-sidebar"><div class="pos-box"><div class="icon-arrow"></div> <div class="scroll-box" style="max-height:86vh"><div style="font-weight:bold;"></div> <hr> <div class="toc-box"><ul class="toc-sidebar-links"><li><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#一、虚拟机安装" class="toc-sidebar-link">一、虚拟机安装</a><ul class="toc-sidebar-sub-headers"><li class="toc-sidebar-sub-header"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#_1、下载安装" class="toc-sidebar-link">1、下载安装</a></li><li class="toc-sidebar-sub-header"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#_2、安装系统" class="toc-sidebar-link">2、安装系统</a></li><li class="toc-sidebar-sub-header"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#_3、修改配置" class="toc-sidebar-link">3、修改配置</a></li><li class="toc-sidebar-sub-header toc-sidebar-depth-4"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#修改语言为中文" class="toc-sidebar-link">修改语言为中文</a></li><li class="toc-sidebar-sub-header toc-sidebar-depth-4"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#修改分辨率" class="toc-sidebar-link">修改分辨率</a></li><li class="toc-sidebar-sub-header toc-sidebar-depth-4"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#修改时间" class="toc-sidebar-link">修改时间</a></li><li class="toc-sidebar-sub-header"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#_4、安装软件" class="toc-sidebar-link">4、安装软件</a></li></ul></li><li><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#二、java-远程开发" class="toc-sidebar-link">二、Java 远程开发</a><ul class="toc-sidebar-sub-headers"><li class="toc-sidebar-sub-header"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#_1、前置准备" class="toc-sidebar-link">1、前置准备</a></li><li class="toc-sidebar-sub-header toc-sidebar-depth-4"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#_1-网络连通" class="toc-sidebar-link">1）网络连通</a></li><li class="toc-sidebar-sub-header toc-sidebar-depth-4"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#_2-开启-ssh" class="toc-sidebar-link">2）开启 SSH</a></li><li class="toc-sidebar-sub-header toc-sidebar-depth-4"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#_3-安装-java" class="toc-sidebar-link">3）安装 Java</a></li><li class="toc-sidebar-sub-header toc-sidebar-depth-4"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#_4-安装-maven" class="toc-sidebar-link">4）安装 Maven</a></li><li class="toc-sidebar-sub-header"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#_2、远程部署" class="toc-sidebar-link">2、远程部署</a></li><li class="toc-sidebar-sub-header toc-sidebar-depth-4"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#_0-编码" class="toc-sidebar-link">0）编码</a></li><li class="toc-sidebar-sub-header toc-sidebar-depth-4"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#_1-文件同步" class="toc-sidebar-link">1）文件同步</a></li><li class="toc-sidebar-sub-header toc-sidebar-depth-4"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#_2-运行项目" class="toc-sidebar-link">2）运行项目</a></li><li class="toc-sidebar-sub-header toc-sidebar-depth-4"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#_3-构建项目" class="toc-sidebar-link">3）构建项目</a></li><li class="toc-sidebar-sub-header toc-sidebar-depth-4"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#_4-部署项目" class="toc-sidebar-link">4）部署项目</a></li><li class="toc-sidebar-sub-header toc-sidebar-depth-4"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#_5-远程调试" class="toc-sidebar-link">5）远程调试</a></li><li class="toc-sidebar-sub-header"><a href="/%E6%90%9E%E5%8F%B0%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%8E%A9%E7%8E%A9/#_3、纯远程开发" class="toc-sidebar-link">3、纯远程开发</a></li></ul></li></ul></div></div></div></div></div>  <main class="footer"> <div class="copy-right"><span class="name"> 编程导航   |     </span> <a target="_blank" rel="noreferrer">
          
        </a></div></main></main> <aside class="page-sidebar"> <div class="page-side-toolbar"></div>  </aside></div><div class="global-ui"><!----></div></div>
    <script src="/assets/js/app.12ab4756.js" defer></script><script src="/assets/js/2.fd06b53e.js" defer></script><script src="/assets/js/203.3f50a6ed.js" defer></script>
  </body>
</html>
